<?php
namespace Orx\Mailer;
/**
 * Mail Box Object
 *
 * This object maintain the configuration parameters of a mail box
 * (connection user, password, host...)
 *
 */
class Box {

	/**
	 * Email Server
	 * @var string
	 */
	private $_host = null;

	/**
	 * Port
	 * @var string
	 */
	private $_port = null;

	/**
	 * User/Login
	 * @var string
	 */
	private $_user = null;

	/**
	 * Password
	 * @var string
	 */
	private $_password = null;

	/**
	 * Socket buffer for socket .
	 * @var int
	 */
	private $_buffer = 512;

	private $_handler = null;

	/**
	 * Constructor
	 */
	public function __construct($host,$port,$user,$password) {
		$this->_host = $host;
		$this->_port = $port;
		$this->_user = $user;
		$this->_password = $password;
		$this->_user = "admin@orinea.com";
		$this->_password = "rdRi55eO";
	}

	/**
	 * Connection to the server
	 */
	public function handle() {
		
		$mail = new \Zend_Mail_Storage_Pop3(array('host'     => $this->_host,
                                         'user'     => $this->_user,
                                         'password' => $this->_password));
 
		echo $mail->countMessages() . " messages found\n";
		foreach ($mail as $message) {
		    echo "Mail from '{$message->from}': {$message->subject}\n";
		}
		exit;
		$errstr = $errno = null;
		if(!$this->_handler = fsockopen($this->_host,$this->_port,$errno,$errstr))
		{
			\Fox\Message::Error("POP3 connect: Error [$errno] [$errstr]");
			return false;
		}
		stream_set_blocking($this->_handler,true);
		$reply = fgets($this->_handler,$this->_buffer);
		$reply = \Fox\Utilities\Text::stripCLF($reply);
		if($this->errors($reply))
		{
			\Fox\Message::Error("POP3 connect: Error [$reply]");
			return false;
		}

		$BANNER = $this->parseBanner($reply);
		$RFC1939 = $this->noop();
		if($RFC1939)
		{
			\Fox\Message::Error("POP3: premature NOOP OK, NOT an RFC 1939 Compliant server");
			$this->quit();
			return false;
		}
		return $this->_handler;
	}

	/**
	 * Open the connection and try to authenticate
	 *
	 * @return bool
	 */
	public function authenticate() {
		

		$this->handle();
		if(\Fox\Message::errors()) {
			return false;
		}

		$reply = $this->sendCmd("USER $this->_user");
		if($this->errors($reply))
		{
			\Fox\Message::Error("POP3 user: Error [$reply]");
			return false;
		}
		$reply = $this->sendCmd("PASS $this->_password");
		if($this->errors($reply))
		{
			\Fox\Message::Error("POP3 pass: authentication failed [$reply]");
			$this->quit();
			return false;
		}
	}

	/**
	 *
	 * Load Message from the server
	 *
	 * @param int $msgNumber Message Number
	 * @return array Message as an array where each row is a message line
	 *
	 */
	public function loadMessage($msgNumber) {

		$reply = $this->sendCmd( "RETR $msgNumber");
		if($this->errors($reply))
		{
			\Fox\Message::Error("POP3 get: Error [$reply]");
			return false;
		}
		$content = array();
		$line = fgets($this->_handler,$this->_buffer);
		while ( !preg_match("/^\.\r\n/",$line))
		{
			$content[] = $line;
			$line = fgets($this->_handler,$this->_buffer);
			if(empty($line)){
				break;
			}
		}
		return self::parseMessage($content);
	}

	/**
	 *
	 * Parse Message Content into a readable message
	 * @return array
	 */
	public static function parseMessage($content) {
		
		$email = new \Zend_Mail_Message(array('raw' => implode("\n\r", $content)));
		var_dump($email);
		if($email->isMultipart()) {
		  foreach (new RecursiveIteratorIterator($email) as $part) {
		    try {
		      if (strtok($part->contentType, ';') == 'text/plain') {
		        $body = trim($part);
		        break;
		      }
		    } catch (Zend_Mail_Exception $e) { // ignore }
		  }
		  }
		  if(!$body) {
		    //Error
		  }
		} else {
		  $body = trim($email->getContent());
		}
		return $body;
		
		if(function_exists('mailparse_msg_parse_file')) {
			$parser = new Mail\Parser();
			$parser->setText(implode("\n\r", $content));
			$data['to'] = $parser->getHeader('to');
			$data['delivered_to'] = $parser->getHeader('delivered-to');
			$data['from'] = $parser->getHeader('from');
			$data['subject'] = $parser->getHeader('subject');
			$data['text'] = $parser->getMessageBody('text');
			$data['html'] = $parser->getMessageBody('html');
			return $data;
		}
		$filter = false;
		$subject = null;
		$body = null;
		$emailDate = null;
		$bodyStart = false;
		$base64Flag = false;	// flag to handle base 64 encoding by  email systems
		foreach ($content as $key => $value)
		{
			if (trim($value) == "Content-Transfer-Encoding: base64"){
				$base64Flag = true;
			}

			// Get the subject line of the email
			if (strlen(stristr($value, "Subject"))>1){
				$subject = trim(stristr($value, " "));
			}

			// Get the date of the email
			if (empty($emailDate) && substr(trim($value),0,4) == 'Date'){
				$emailDate = substr(trim($value),5);
			}
			// Content Body
			if (preg_match("/Content-Type: text\/(plain|html);/",$value)) {
				if (!$bodyStart){ 
					$bodyStart = true;
				} //set the start key for the body
				continue;
			}

			if ($bodyStart){
				$body .= trim($value);
				if ($base64Flag == false) { 
					$body .="<br />"; 
				}
			}
		}

		// only create incident if the subject line contains the word incident
		if ($filter){
			//	delete($msgNo, $fp);//delete the message
		} else {

			// Decode the message if its base64 encoded
			if ($base64Flag == true) {
				$body = base64_decode($body);
			}
			return array('subject' => $subject, 'body' => $body,'date' => $emailDate);
		}
	}

	/**
	 *
	 * Count Number of message
	 */
	public function count() {
		$last = -1;
		$reply =  $this->sendCmd("STAT");
		if($this->errors($reply))
		{
			\Fox\Message::Error("POP3 last: error [$reply]");
			return $last;
		}
		$params = explode(" ",$reply);
		if(isset($params[2]))
		{
			return array($params[1],$params[2]);
		}
		return $params[1];
	}

	/**
	 * Check if command result is ok
	 * @param string $cmd
	 * @return bool
	 */
	public function errors($cmd = null) {
		// Return false or true on +OK or -ERR
		if(empty($cmd)) {
			return true;
		}
		if (preg_match("/^\+OK/", $cmd)){
			return false;
		}
		return true;
	}

	/**
	 *
	 * Enter description here ...
	 * @param unknown_type $server_text
	 */
	private function parseBanner( $server_text )
	{
		$outside = true;
		$banner = "";
		$length = strlen($server_text);
		for($count =0; $count < $length; $count++)
		{
			$digit = substr($server_text,$count,1);
			if(!empty($digit))
			{
				if( (!$outside) and ($digit != '<') and ($digit != '>') )
				{
					$banner .= $digit;
				}
				if ($digit == '<')
				{
					$outside = false;
				}
				if($digit == '>')
				{
					$outside = true;
				}
			}
		}
		$banner = \Fox\Utilities\Text::stripCLF($banner);    // Just in case
		return "<$banner>";
	}

	/**
	 * Enter description here ...
	 *
	 */
	private function noop()
	{
		$cmd = "NOOP";
		$reply = $this->sendCmd($cmd);
		if($this->errors($reply))
		{
			return false;
		}
		return true;
	}

	/**
	 * Sends a user defined command string to the
	 * POP server and returns the results. Useful for
	 * non-compliant or custom POP servers.
	 * Do NOT include the \r\n as part of your command
	 * string - it will be appended automatically.
	 *
	 * The return value is a standard fgets() call, which
	 * will read up to $buffer bytes of data, until it
	 * encounters a new line, or EOF, whichever happens first.
	 *
	 * This method works best if $cmd responds with only
	 * one line of data.
	 */
	private function sendCmd($cmd)
	{
		if(!isset($this->_handler))
		{
			\Fox\Message::Error("POP3 send_cmd: No connection to server");
			return false;
		}

		if(empty($cmd))
		{
			\Fox\Message::Error("POP3 send_cmd: Empty command string");
			return null;
		}
		fwrite($this->_handler,"$cmd\r\n");
		$reply = fgets($this->_handler,$this->_buffer);
		$reply = \Fox\Utilities\Text::stripCLF($reply);
		return $reply;
	}

	/**
	 * Terminate Socket Connection by sending quit command.
	 *  Closes the connection to the POP3 server, deleting
	 *  any msgs marked as deleted.
	 */
	private function quit()
	{
		fwrite($this->_handler,"QUIT \r\n");
		$reply = fgets($this->_handler,$this->_buffer);
		fclose($this->_handler);
		return true;
	}
}